#include <zephyr.h>
#include <sys/printk.h>
#include <shell/shell.h>
#include <shell/shell_uart.h>
#include <logging/log.h>

#include <version.h>
#include <stdlib.h>
#include <gpio.h>
#include <board.h>
#include <pwm.h>
#include <led.h>
#include <sensor.h>
#include "nrf52.h"
#include "test.h"

LOG_MODULE_REGISTER(app, LOG_LEVEL_DBG);

static int cmd_led(const struct shell *shell, size_t argc, char **argv)
{
	struct device *gpio_dev;
	int index, onoff;
	struct device *led_dev;

	led_dev = device_get_binding("NRF_52");
	__ASSERT(led_dev,
			 "LED init failed. Cannot find NRF_52");

	gpio_dev = device_get_binding(DT_GPIO_P0_DEV_NAME);

	if (argc != 3)
	{
		printk("Set Led param error\n");
		return 0;
	}

	index = atoi(argv[1]);
	onoff = atoi(argv[2]);
	printk("Set Led %d to %d\n", index, onoff);

	switch (index)
	{
	case 11:
		led_on(led_dev, LED_BLUE_PIN);
		break;
	case 21:
		led_off(led_dev, LED_BLUE_PIN);
		break;
	case 31:
		led_blink(led_dev, LED_BLUE_PIN, 500, 1000);
		break;
	case 41:
		led_set_brightness(led_dev, LED_BLUE_PIN, onoff);
		break;
	default:
		break;
	}
	return 0;
}

#define PERIOD (USEC_PER_SEC / 50)

static int cmd_pwm(const struct shell *shell, size_t argc, char **argv)
{
	struct device *pwm_dev;
	int index, level, pulse_width;

	pwm_dev = device_get_binding(PWM_DRIVER);

	if (argc != 3)
	{
		printk("Set Led param error\n");
		return 0;
	}

	index = atoi(argv[1]);
	level = atoi(argv[2]);

	pulse_width = level * 200;
	if (pulse_width > PERIOD)
	{
		pulse_width = PERIOD;
	}

	printk("Set Led %d to %d(%d-%d)\n", index, level, pulse_width, PERIOD);

	switch (index)
	{
	case 0:
		pwm_pin_set_usec(pwm_dev, LED_RED_PIN, PERIOD, pulse_width);
		break;
	case 1:
		pwm_pin_set_usec(pwm_dev, LED_BLUE_PIN, PERIOD, pulse_width);
		break;
	case 2:
		pwm_pin_set_usec(pwm_dev, LED_GREEN_PIN, PERIOD, pulse_width);
		break;
	default:
		break;
	}
	return 0;
}

static int cmd_dht(const struct shell *shell, size_t argc, char **argv)
{
	struct sensor_value temp, humidity;
	struct device *dev = device_get_binding("DHT11"); //根据Device name获取驱动
	printk("dev %p name %s\n", dev, dev->config->name);
	sensor_sample_fetch(dev);								  //从dh11读取数据
	sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); //读取温度
	sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity); //读取湿度

	printk("temp: %d.%06d; humidity: %d.%06d\n",
		   temp.val1, temp.val2, humidity.val1, humidity.val2);
	return 0;
}


static int cmd_version(const struct shell *shell, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	printk("Zephyr version %s\n", KERNEL_VERSION_STRING);
	return 0;
}

static int cmd_clk(const struct shell *shell, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	printk("Zephyr CLK %llu\n", (u64_t)sys_clock_hw_cycles_per_sec);
	printk("Zephyr trick %u\n", k_cycle_get_32());
	k_sleep(100);
	printk("Zephyr trick now %u\n", k_cycle_get_32());
	return 0;
}

static int cmd_display(const struct shell *shell, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	distest_set(argv[1]);
	LOG_ERR("Frank log %s\n", argv[1]);
	return 0;
}

SHELL_CMD_REGISTER(ver, NULL, "Show kernel version", cmd_version);
SHELL_CMD_REGISTER(led, NULL, "set led", cmd_led);
SHELL_CMD_REGISTER(pwm, NULL, "set pwm", cmd_pwm);
SHELL_CMD_REGISTER(dht, NULL, "get dht", cmd_dht);
SHELL_CMD_REGISTER(clk, NULL, "get clk", cmd_clk);
SHELL_CMD_REGISTER(display, NULL, "set display", cmd_display);

void main(void)
{
	//spinor_test_init();
	//net_test_init();
	//bt_test_init();
	//distest_init();
	//fstest_init();
	//lvgltest_init();
	use_space_test();
}
